package top.suven.http.oauth.authorize;

import top.suven.http.oauth.token.OAuthAuthxRequest;
import top.suven.http.oauth.validator.AbstractOAuthResponseTypeValidator;
import com.alibaba.fastjson.JSONObject;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.suven.base.util.utilize.JsonUtils;


/**
 * @ClassName: AbstractAuthorizeHandler.java
 * @Description: OAUTH2.0的认证服务, auth 请求验证
 * @Author suven.wang
 * @Date 2018/7/26 18:01
 * @Copyright: (c) 2018 gc by https://www.gc.com.cn/
 * @Version : 1.0.0
 *  --------------------------------------------------------
 *  modifyer    modifyTime                 comment
 *
 *  --------------------------------------------------------
 */
public abstract class AbstractOAuthAuthorizeHandler implements OAuthHandler {

    private static final Logger logger = LoggerFactory.getLogger(AbstractOAuthAuthorizeHandler.class);


    protected OAuthAuthxRequest oauthRequest;
    private OAuthResponse oAuthResponse;





    public JSONObject getResponse(){
        if(oAuthResponse == null){
            return null;
        }
        return JsonUtils.readValue(this.oAuthResponse.getBody(),JSONObject.class);
    }

    private void setResponse(OAuthResponse oAuthResponse){
        this.oAuthResponse = oAuthResponse;
    }

    /**
     * 校验参数ResponseType.CODE
     * @param oauthRequest
     * @return
     */
    @Override
    public boolean support(OAuthAuthxRequest oauthRequest) {
        return oauthRequest.isCode();
    }

    //所有业务流程
    @Override
    public boolean handle(OAuthAuthxRequest oauthRequest) throws  OAuthSystemException {
        this.oauthRequest =  oauthRequest;
        try {
            OAuthResponse oAuthResponse = validateFailed();
            if(null != oAuthResponse){
                this.setResponse(oAuthResponse);
                return false;
            }
             //3.handleResponse
            oAuthResponse = handleResponse();
            if(null == oAuthResponse){
                oAuthResponse = getValidator().successDefault();
            }
            this.setResponse(oAuthResponse);
            return true;
        }catch (Exception e){

        }
        return false;

    }


    /**
     * 共性校验,只要有一个属性校验失败,就结束并返回true;
     * @return
     * @throws OAuthProblemException
     * @throws OAuthSystemException
     */

    protected OAuthResponse validateFailed() throws  OAuthSystemException {
        AbstractOAuthResponseTypeValidator validator = getValidator();
        logger.debug("Use [{}] validate client: {}", validator, oauthRequest.getClientId());

        final boolean validate = validator.validate();
        if(! validate){
            return validator.getResponse();
        }
        return handleAfterValidation(validator);
    }

    protected abstract AbstractOAuthResponseTypeValidator getValidator();

    /**
     * 个性属性校验
     * @return
     * @throws OAuthProblemException
     * @throws OAuthSystemException
     */
    protected abstract OAuthResponse handleAfterValidation(AbstractOAuthResponseTypeValidator validator)throws OAuthSystemException;

    /**
     * 返回结果组装
     * @throws OAuthSystemException
     **/
    //Handle custom response content
    protected abstract OAuthResponse handleResponse() throws OAuthSystemException;


}